package org.apache.ofbiz.services;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.doc.domain.Content;
import org.apache.ofbiz.api.util.BusinessException;
import org.apache.ofbiz.api.util.DateKit;
import org.apache.ofbiz.base.util.*;
import org.apache.ofbiz.constant.ConstKit;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericDelegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.condition.EntityCondition;
import org.apache.ofbiz.entity.condition.EntityOperator;
import org.apache.ofbiz.entity.model.DynamicViewEntity;
import org.apache.ofbiz.entity.model.ModelKeyMap;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 北京XXX信息技术有限公司-版权所有
 *
 * @author yuanpingfang
 * @version 1.0
 * @Package org.apache.ofbiz.services
 * @ClassName ContentExtServices
 * @Description 内容服务
 * @date 2021-4-1 14:39
 */
public class ContentExtServices {
    public static final String module = ContentExtServices.class.getName();

    public static Map<String, Object> createContentExt(DispatchContext ctx, Map<String, Object> context) {
        //LocalDispatcher dispatcher = ctx.getDispatcher();
        GenericDelegator delegator = (GenericDelegator) ctx.getDelegator();
        //Locale locale = (Locale) context.get("locale");
        com.alibaba.fastjson.JSONObject content = (JSONObject) context.get("content");
        if (UtilValidate.isEmpty(content)) {
            return ServiceUtil.returnError("content不能为空!");
        }
        //String contentId = (String) content.get("contentId");// 文档标识
        String contentTypeId = (String) content.get("contentTypeId");// 文档类型

        //String ownerContentId = (String) content.get("ownerContentId");// 拥有者内容标识
        //String decoratorContentId = (String) content.get("decoratorContentId");// 装饰文档标识
        //String instanceOfContentId = (String) content.get("instanceOfContentId");// 文档标识实例
        String objectInfo = (String) content.get("objectInfo");// 附件
        //String templateDataResourceId = (String) content.get("templateDataResourceId");// 模板数据资源标识
        //String dataSourceId = (String) content.get("dataSourceId");// 数据源标识
        String statusId = (String) content.get("statusId");// 文档状态
        //String privilegeEnumId = (String) content.get("privilegeEnumId");// 特权枚举标识
        //String serviceName = (String) content.get("serviceName");// 服务名称
        //String customMethodId = (String) content.get("customMethodId");// 自定义方法标识
        String contentName = (String) content.get("contentName");// 文档名称
        //String description = (String) content.get("description");// 文档描述
        //String localeString = (String) content.get("localeString");// 语言字符串
        //String mimeTypeId = (String) content.get("mimeTypeId");// Mime类型标识
        //String characterSetId = (String) content.get("characterSetId");// 字符集标识
        //Long childLeafCount = (Long) content.get("childLeafCount");// 下级内容资源计数
        //Long childBranchCount = (Long) content.get("childBranchCount");// 下级分支计数
        Timestamp createdDate = (Timestamp) content.get("createdDate");// 创建日期
        String createdByUserLogin = (String) content.get("createdByUserLogin");// 创建人标识
        //Timestamp lastModifiedDate = (Timestamp) content.get("lastModifiedDate");// 上次修改日期
        //String lastModifiedByUserLogin = (String) content.get("lastModifiedByUserLogin");// 上次修改用户
        //Date lastUpdatedStamp = (Timestamp) content.get("lastUpdatedStamp");// 最后更新时间
        //Date lastUpdatedTxStamp = (Timestamp) content.get("lastUpdatedTxStamp");// 最后更新事务时间
        //Date createdStamp = (Timestamp) content.get("createdStamp");// 创建时间
        //Date createdTxStamp = (Timestamp) content.get("createdTxStamp");// 创建事务时间
        String version = (String) content.get("version");// 版本号
        //String partyId = (String) content.get("partyId");// 机构ID或用户ID
        String parentFolderId = (String) content.get("parentFolderId");// 上级文件夹ID

        String partyId = (String) content.get("partyId");// 机构ID或用户ID
        if (UtilValidate.isEmpty(partyId) && UtilValidate.isEmpty(parentFolderId)) {
            return ServiceUtil.returnError("partyId和parentFolderId不能同时为空!");
        }
        if (!ConstKit.CONTENT_TYPE_FOLDER.equals(contentTypeId) && UtilValidate.isEmpty(objectInfo)) { // 如果不是文件夹，要上传附件
            return ServiceUtil.returnError("请上传附件！");
        }
        String contentId = delegator.getNextSeqId("Content");// 生成主键
        statusId = ConstKit.CTNT_INITIAL_DRAFT;// CTNT_INITIAL_DRAFT-草稿  CTNT_IN_PROGRESS-审批中 CTNT_PUBLISHED-已发布
        if (ConstKit.CONTENT_TYPE_FOLDER.equals(contentTypeId)) {// 如果是文件夹，状态直接是CTNT_PUBLISHED-已发布
            statusId = ConstKit.CTNT_PUBLISHED;
        }
        try {
            if (UtilValidate.isNotEmpty(partyId)) {
                // 创建机构和内容的关联关系
                GenericValue partyContentGv = delegator.makeValue("PartyContent");
                partyContentGv.set("partyId", partyId);
                partyContentGv.set("contentId", contentId);
                partyContentGv.set("partyContentTypeId", contentTypeId);
                partyContentGv.set("fromDate", UtilDateTime.nowTimestamp());
                partyContentGv.create();
            } else {
                // 创建和上层文件夹的关联关系
                GenericValue contentAssocGv = delegator.makeValue("ContentAssoc");
                contentAssocGv.set("contentId", parentFolderId);
                contentAssocGv.set("contentIdTo", contentId);
                contentAssocGv.set("contentAssocTypeId", ConstKit.CONTENT_ASSOC_TYPE_SUB);
                contentAssocGv.set("fromDate", UtilDateTime.nowTimestamp());
                contentAssocGv.set("createdDate", UtilDateTime.nowTimestamp());
                contentAssocGv.set("createdByUserLogin", String.valueOf(context.get("userId")));
                contentAssocGv.create();
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }

        if (UtilValidate.isEmpty(createdByUserLogin)) {
            content.put("createdByUserLogin", String.valueOf(context.get("userId")));
        }
        if (UtilValidate.isEmpty(version)) {
            content.put("version", "1");
        }
        if (UtilValidate.isEmpty(createdDate)) {
            content.put("createdDate", UtilDateTime.nowTimestamp());
        }
        content.put("statusId", statusId);
        try {
            if (UtilValidate.isNotEmpty(objectInfo)) { // 代表上传了附件
                GenericValue dataResource = delegator.makeValue("DataResource");
                dataResource.set("dataResourceId", contentId);// 因为是一对一,所以把contentId作为dataResourceId
                dataResource.set("dataResourceTypeId", "OFBIZ_FILE");
                dataResource.set("dataTemplateTypeId", "NONE");
                dataResource.set("statusId", statusId);
                dataResource.set("dataResourceName", contentName);
                dataResource.set("objectInfo", objectInfo);
                dataResource.set("mimeTypeId", "application/pdf");//可以根据objectInfo得到
                dataResource.set("isPublic", "Y");
                dataResource.set("createdDate", UtilDateTime.nowTimestamp());
                dataResource.set("createdByUserLogin", String.valueOf(context.get("userId")));
                dataResource.create();// 创建附件信息
                context.put("dataResourceId", contentId);// 重新赋值
            }
            GenericValue contentGv = delegator.makeValue("Content");
            contentGv.set("contentId", contentId);
            contentGv.setNonPKFields(content);
            contentGv.create();//创建文档
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return ServiceUtil.returnSuccess();
    }

    public static Map<String, Object> updateContentExt(DispatchContext ctx, Map<String, Object> context) {
        LocalDispatcher dispatcher = ctx.getDispatcher();
        GenericDelegator delegator = (GenericDelegator) ctx.getDelegator();
        //Locale locale = (Locale) context.get("locale");
        String contentId = (String) context.get("contentId");// 文档标识
        //String contentTypeId = (String) context.get("contentTypeId");// 文档类型
        //String ownerContentId = (String) context.get("ownerContentId");// 拥有者内容标识
        //String decoratorContentId = (String) context.get("decoratorContentId");// 装饰文档标识
        //String instanceOfContentId = (String) context.get("instanceOfContentId");// 文档标识实例
        String objectInfo = (String) context.get("objectInfo");// 附件
        String dataResourceId = (String) context.get("dataResourceId");// 附件ID,不为空则代表新增的时候上传过
        //String templateDataResourceId = (String) context.get("templateDataResourceId");// 模板数据资源标识
        //String dataSourceId = (String) context.get("dataSourceId");// 数据源标识
        String statusId = (String) context.get("statusId");// 文档状态
        //String privilegeEnumId = (String) context.get("privilegeEnumId");// 特权枚举标识
        //String serviceName = (String) context.get("serviceName");// 服务名称
        //String customMethodId = (String) context.get("customMethodId");// 自定义方法标识
        String contentName = (String) context.get("contentName");// 文档名称
        String description = (String) context.get("description");// 文档描述
        //String localeString = (String) context.get("localeString");// 语言字符串
        //String mimeTypeId = (String) context.get("mimeTypeId");// Mime类型标识
        //String characterSetId = (String) context.get("characterSetId");// 字符集标识
        //Long childLeafCount = (Long) context.get("childLeafCount");// 下级内容资源计数
        //Long childBranchCount = (Long) context.get("childBranchCount");// 下级分支计数
        Timestamp createdDate = (Timestamp) context.get("createdDate");// 创建日期
        String createdByUserLogin = (String) context.get("createdByUserLogin");// 创建人标识
        //Timestamp lastModifiedDate = (Timestamp) context.get("lastModifiedDate");// 上次修改日期
        //String lastModifiedByUserLogin = (String) context.get("lastModifiedByUserLogin");// 上次修改用户
        //Date lastUpdatedStamp = (Timestamp) context.get("lastUpdatedStamp");// 最后更新时间
        //Date lastUpdatedTxStamp = (Timestamp) context.get("lastUpdatedTxStamp");// 最后更新事务时间
        //Date createdStamp = (Timestamp) context.get("createdStamp");// 创建时间
        //Date createdTxStamp = (Timestamp) context.get("createdTxStamp");// 创建事务时间
        String version = (String) context.get("version");// 版本号

        if (UtilValidate.isEmpty(contentId)) {
            return ServiceUtil.returnError("contentId不能为空!");
        }
        GenericValue content = null;
        try {
            content = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryFirst();
            if (UtilValidate.isEmpty(content)) {
                return ServiceUtil.returnError("请确认参数[contentId]!");
            }
            if (!ConstKit.CTNT_INITIAL_DRAFT.equals(content.getString("statusId")) && !ConstKit.CONTENT_TYPE_FOLDER.equals(content.getString("contentTypeId"))) {
                return ServiceUtil.returnError("文档不允许修改!");
            }
            GenericValue dataResource = content.getRelatedOne("DataResource", true);
            // 1.附件分2种,创建时,未上传附件
            // 2.修改的时候删除了附件
            // 3.规定必须传附件,如果变更了附件,则自动创建新版本
            if (UtilValidate.isNotEmpty(dataResource)) {
                if (UtilValidate.isEmpty(objectInfo)) { // 代表新增的时候有附件,现在是删除了附件
                    //1.将附件和内容的关系解除
                    context.put("dataResourceId", null);
                    //2.将附件的状态标记为不可用“DISABLED”
                    dataResource.set("statusId", ConstKit.DISABLED);
                    dataResource.store();
                } else if (!objectInfo.equals(dataResource.getString("objectInfo"))) { // 代表该文档有附件，并且附件有变化
                    // 递增版本号
                    // 新增文档和附件
                    context.put("version", UtilMisc.toInteger(content.getString("version")) + 1);
                    Map<String, Object> serverMap = dispatcher.runSync("createContentExt", context);
                    if (!ServiceUtil.isSuccess(serverMap)) {
                        return serverMap;
                    }
                }
            }
            // 本次和上次的附件一致,只是该其他内容,非附件
            context.put("lastModifiedByUserLogin", String.valueOf(context.get("userId")));
            context.put("lastModifiedDate", UtilDateTime.nowTimestamp());
            content.setNonPKFields(context);
            content.store();
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return ServiceUtil.returnSuccess();
    }

    /**
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Title selectContentList
     * @Description 查询内容列表
     * @author yuanpingfang
     * @date 2021-4-17 10:13
     */
    public static Map<String, Object> selectContentList(DispatchContext dctx, Map<String, Object> context) {
        LocalDispatcher dispatcher = dctx.getDispatcher();
        Content content = (Content) context.get("content");
        Integer pageNum = (Integer) context.get("pageNum");
        Integer pageSize = (Integer) context.get("pageSize");
        String orderBy = (String) context.get("orderBy");
        Map<String, Object> params = UtilGenerics.checkMap(content.getParams());
        if (UtilValidate.isEmpty(orderBy)) {
            orderBy = "-lastUpdatedStamp";
        }
        String entityName = "Content";
        List<EntityCondition> conditions = new ArrayList<>();
        if (UtilValidate.isNotEmpty(content.getContentId())) {
            conditions.add(EntityCondition.makeCondition("contentId", EntityOperator.EQUALS, content.getContentId()));
        }
        if (UtilValidate.isNotEmpty(content.getContentTypeId())) {
            conditions.add(EntityCondition.makeCondition("contentTypeId", EntityOperator.EQUALS, content.getContentTypeId()));
        }
        if (UtilValidate.isNotEmpty(content.getStatusId())) {
            conditions.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, content.getStatusId()));
        }
        if (UtilValidate.isNotEmpty(content.getContentName())) {
            conditions.add(EntityCondition.makeCondition("contentName", EntityOperator.LIKE, "%" + content.getContentName() + "%"));
        }
        if (UtilValidate.isNotEmpty(content.getCreatedByUserLogin())) {
            conditions.add(EntityCondition.makeCondition("createdByUserLogin", EntityOperator.EQUALS, content.getCreatedByUserLogin()));
        }
        if (UtilValidate.isNotEmpty(content.getVersion())) {
            conditions.add(EntityCondition.makeCondition("version", EntityOperator.EQUALS, content.getVersion()));
        }
        if (UtilValidate.isNotEmpty(params)) {
            String beginCreatedDate = (String) params.get("beginCreatedDate");
            String endCreatedDate = (String) params.get("endCreatedDate");
            try {
                if (UtilValidate.isNotEmpty(beginCreatedDate)) {
                    Timestamp beginCreatedDateTs = DateKit.toTimestamp(beginCreatedDate, DateKit.defForDate);
                    conditions.add(EntityCondition.makeCondition("createdStamp", EntityOperator.GREATER_THAN_EQUAL_TO, UtilDateTime.getDayStart(beginCreatedDateTs)));
                }
                if (UtilValidate.isNotEmpty(endCreatedDate)) {
                    Timestamp endCreatedDateTs = DateKit.toTimestamp(endCreatedDate, DateKit.defForDate);
                    conditions.add(EntityCondition.makeCondition("createdStamp", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.getDayEnd(endCreatedDateTs)));
                }
            } catch (BusinessException e) {
                return ServiceUtil.returnError(e.getMessage());
            }
        }

        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("entityName", entityName);
        queryMap.put("pageNum", pageNum);
        queryMap.put("pageSize", pageSize);
        queryMap.put("queryCondition", EntityCondition.makeCondition(conditions));
        queryMap.put("orderBy", orderBy);// 多个排序字段 "|" 符连接
        queryMap.put("fields", "");// 多个查询字段 "|" 符连接
        //queryMap.put("distinct","Y");
        Map<String, Object> queryPageMap = null;
        try {
            queryPageMap = dispatcher.runSync("queryPageList", queryMap);
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return queryPageMap;
    }

    /**
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Title selectContentById
     * @Description 查询内容
     * @author yuanpingfang
     * @date 2021-4-17 10:14
     */
    public static Map<String, Object> selectContentById(DispatchContext dctx, Map<String, Object> context) {
        Delegator delegator = dctx.getDelegator();
        String contentId = (String) context.get("contentId");
        GenericValue contentValue = null;
        try {
            DynamicViewEntity dve = new DynamicViewEntity();
            dve.addMemberEntity("CO", "Content");
            dve.addAliasAll("CO", "", null); // no prefix
            dve.addMemberEntity("DR", "DataResource");
            dve.addAliasAll("DR", "", null); // no prefix
            dve.addViewLink("CO", "DR", Boolean.TRUE, ModelKeyMap.makeKeyMapList("contentId", "dataResourceId"));
            contentValue = EntityQuery.use(delegator).from(dve).where("contentId", contentId).queryFirst();
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        Map<String, Object> returnMap = ServiceUtil.returnSuccess();
        returnMap.put("content", contentValue);
        return returnMap;
    }


    /**
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Title deleteContentByIds
     * @Description 批量删除内容服务
     * @author yuanpingfang
     * @date 2021-4-17 13:08
     */
    public static Map<String, Object> deleteContentByIds(DispatchContext dctx, Map<String, Object> context) {
        Delegator delegator = dctx.getDelegator();
        List<String> contentIds = UtilGenerics.checkList(context.get("contentIds"));
        try {
            if (UtilValidate.isEmpty(contentIds)) {
                return ServiceUtil.returnError("请选择要删除的文档！");
            }
            for (String contentId : contentIds) {
                GenericValue contentValue = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryFirst();
                if (UtilValidate.isNotEmpty(contentValue)) {
                    GenericValue dataResource = contentValue.getRelatedOne("DataResource", false);
                    if (UtilValidate.isNotEmpty(dataResource)) { // 如果关联了附件,将附件标记为不可用,后期可以考虑删除失效的数据和对应的磁盘文件
                        dataResource.set("lastModifiedDate", UtilDateTime.nowTimestamp());
                        dataResource.set("lastModifiedByUserLogin", String.valueOf(context.get("userId")));
                        dataResource.set("statusId", ConstKit.DISABLED);
                        dataResource.store();
                    }
                    // 将附件与机构解除绑定
                    delegator.removeByAnd("PartyContent", UtilMisc.toMap("contentId", contentId));
                    // 与上级文件夹解除绑定
                    delegator.removeByAnd("ContentAssoc", UtilMisc.toMap("contentIdTo", contentId));
                    contentValue.remove();
                }
            }
            //delegator.removeByCondition("Content", EntityCondition.makeCondition("contentId", EntityOperator.IN, contentIds));
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return ServiceUtil.returnSuccess();
    }

    /**
     * @param
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @Title moveContent
     * @Description 移动文件或文件夹
     * @author yuanpingfang
     * @date 2021-4-17 13:08
     */
    public static Map<String, Object> moveContent(DispatchContext dctx, Map<String, Object> context) {
        Delegator delegator = dctx.getDelegator();
        String targetContentId = (String) context.get("targetContentId");//目标文件夹ID
        List<String> contentIds = UtilGenerics.checkList(context.get("contentIds"));
        if (UtilValidate.isEmpty(targetContentId)) {
            return ServiceUtil.returnError("请选择目标文件夹！");
        }
        if (UtilValidate.isEmpty(contentIds)) {
            return ServiceUtil.returnError("请选择要移动的文件或文件夹！");
        }
        try {

            // 将待移动的文件或文件夹与它的上级文件夹解除关系
            EntityCondition condition = EntityCondition.makeCondition("contentIdTo", EntityOperator.IN, contentIds);
            delegator.removeByCondition("ContentAssoc", condition);

            // 解除和机构的关系
            condition = EntityCondition.makeCondition("contentId", EntityOperator.IN, contentIds);
            delegator.removeByCondition("PartyContent", condition);

            List<GenericValue> createList = new ArrayList<>();
            // 需要判断是移动到机构还是文件夹下面了
            Long count = EntityQuery.use(delegator).from("Content").where("contentId", targetContentId).cache().queryCount();
            if(count>0){ // 代表目标位置是文件夹
                for (String contentId : contentIds) {
                    GenericValue contentAssoc = delegator.makeValue("ContentAssoc");
                    contentAssoc.set("contentId", targetContentId);
                    contentAssoc.set("contentIdTo", contentId);
                    contentAssoc.set("contentAssocTypeId", ConstKit.CONTENT_ASSOC_TYPE_SUB);
                    contentAssoc.set("fromDate", UtilDateTime.nowTimestamp());
                    contentAssoc.set("createdDate", UtilDateTime.nowTimestamp());
                    contentAssoc.set("createdByUserLogin", String.valueOf(context.get("userId")));
                    createList.add(contentAssoc);
                }
            } else { // 代表目标位置是机构
                for (String contentId : contentIds) {
                    GenericValue contentValue = EntityQuery.use(delegator).from("Content").where("contentId", contentId).cache().queryFirst();
                    if(UtilValidate.isNotEmpty(contentValue)){
                        GenericValue contentAssoc = delegator.makeValue("PartyContent");
                        contentAssoc.set("partyId", targetContentId);
                        contentAssoc.set("contentId", contentId);
                        contentAssoc.set("partyContentTypeId", contentValue.getString("contentTypeId"));
                        contentAssoc.set("fromDate", UtilDateTime.nowTimestamp());
                        createList.add(contentAssoc);
                    }
                }
            }
            delegator.createAllBatch(createList);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        return ServiceUtil.returnSuccess();
    }


}
